package com.ashlikun.zxing

import android.content.Context
import android.graphics.PointF
import android.util.AttributeSet
import android.view.View
import android.view.View.OnClickListener
import android.widget.ImageView
import androidx.lifecycle.LifecycleOwner
import com.ashlikun.camera.scan.AnalyzeResult
import com.ashlikun.camera.scan.BaseCameraScanView
import com.ashlikun.camera.scan.analyze.Analyzer
import com.ashlikun.zxing.analyze.LightAnalyzer
import com.ashlikun.zxing.analyze.ResultAnalyzer
import com.google.zxing.Result

/**
 * 基于zxing实现的扫码识别 - 相机扫描基类
 *
 *
 * 通过继承 [ZxingBaseCameraScanView]可快速实现扫码识别
 */
open class ZxingBaseCameraScanView @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0) :
    BaseCameraScanView<Result>(context, attrs, defStyleAttr, defStyleRes) {
    protected var ivFlashlight: View? = null

    //多个二维码的点位选择
    protected var multiplePoints: MutableList<View> = ArrayList()
    protected val lightAnalyzer by lazy {
        LightAnalyzer { isLight: Boolean ->
            if (ivFlashlight != null) {
                if (isLight) {
                    if (ivFlashlight!!.visibility == VISIBLE && !cameraScan.isTorchEnabled) {
                        ivFlashlight!!.visibility = INVISIBLE
                        ivFlashlight!!.isSelected = false
                    }
                } else {
                    if (ivFlashlight!!.visibility != VISIBLE) {
                        ivFlashlight!!.visibility = VISIBLE
                        ivFlashlight!!.isSelected = cameraScan.isTorchEnabled
                    }
                }
            }
        }
    }
    var resultAnalyzer = ResultAnalyzer(lightAnalyzer)
        protected set
    protected var onShowMultiplePoints: OnShowMultiplePoints? = null

    /**
     * 显示多个点位的时候回调
     */
    interface OnShowMultiplePoints {
        fun onShowPoints()
    }

    override fun inflateView(context: Context, attrs: AttributeSet, defStyleAttr: Int, defStyleRes: Int) {
        super.inflateView(context, attrs, defStyleAttr, defStyleRes)
    }

    override fun initUI(owner: LifecycleOwner) {
        super.initUI(owner)
        val ivFlashlightId = flashlightId
        if (ivFlashlightId != NO_ID && ivFlashlightId != 0) {
            ivFlashlight = findViewById(ivFlashlightId)
            ivFlashlight!!.setOnClickListener(OnClickListener { v: View? ->
                ivFlashlight!!.setSelected(onClickFlashlight())
                if (!ivFlashlight!!.isSelected() && lightAnalyzer.bright == true) {
                    ivFlashlight!!.setVisibility(INVISIBLE)
                }
            })
        }
        lightAnalyzer.enable = ivFlashlight != null
    }

    override fun createAnalyzer() = resultAnalyzer

    override fun getLayoutId(): Int {
        return R.layout.xzxing_camera_scan
    }

    override fun getPreviewViewId(): Int {
        return R.id.previewView
    }

    open val flashlightId: Int
        get() = R.id.ivFlashlight

    override fun onAttachedToWindow() {
        super.onAttachedToWindow()
        lightAnalyzer.setHandler(handler)
    }

    override fun onScanResultCallback(result: AnalyzeResult<Result>) {
        if (result.isMultipleResult && resultAnalyzer.dataAnalyzer?.isMultipleCode == true) {
            //停止扫描，显示点位
//            stopCamera();
            showMultiplePoints(result)
            if (onShowMultiplePoints != null) {
                onShowMultiplePoints!!.onShowPoints()
            }
            //停止识别
            setAnalyzeImage(false)
        } else {
            super.onScanResultCallback(result)
        }
    }

    /**
     * 显示多个码对应的位置，然后用户选择后回调
     * resultPoints = [(647.0,1005.0), (656.0,896.5), (770.0,903.5), (745.0,997.0)]
     *
     * @param result 扫描结果
     */
    protected fun showMultiplePoints(result: AnalyzeResult<Result>) {
        cleanMultiplePoints()
        //获取当前的相机图片显示
        val viewBg = ImageView(context)
        viewBg.setImageBitmap(previewView.bitmap)
        addView(viewBg, previewView.layoutParams)
        multiplePoints.add(viewBg)
        val bitmapHeight = result.bitmap!!.height
        val bitmapWidth = result.bitmap!!.width
        val bitmapRotation = result.frameMetadata.rotation
        for (itemResult in result.resultAll) {
            val avargPoint = PointF()
            for (item in itemResult.resultPoints) {
                val x = item.x
                val y = item.y
                avargPoint.x += x
                avargPoint.y += y
            }
            avargPoint.x /= itemResult.resultPoints.size.toFloat()
            avargPoint.y /= itemResult.resultPoints.size.toFloat()
            val biliX = width / bitmapWidth.toFloat()
            val biliY = height / bitmapHeight.toFloat()
            val biliMax = Math.max(biliX, biliY)
            //缩放后的差值
            val diffX = bitmapWidth * biliMax - width
            val diffY = bitmapHeight * biliMax - height
            avargPoint.x = avargPoint.x * biliMax - diffX / 2
            avargPoint.y = avargPoint.y * biliMax - diffY / 2
            //            CameraXLogUtils.e("点位信息 " + " viewWidth = " + previewView.getWidth() + " viewHeight = " + previewView.getHeight() + avargPoint + "  getWidth = " + getWidth() +
//                    " getHeight = " + getHeight() + "   bitmapWidth = " + bitmapWidth + "   bitmapHeight = " + bitmapHeight + "  bitmapRotation = " + bitmapRotation);
            val layoutParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
            val view = ImageView(context)
            view.x = avargPoint.x
            view.y = avargPoint.y
            view.setBackgroundResource(R.drawable.xzxing_ic_qr_loc)
            addView(view, layoutParams)
            view.post {
                view.x = avargPoint.x - view.width / 2
                view.y = avargPoint.y - view.height / 2
            }
            view.setOnClickListener { v: View? ->
                val list = mutableListOf<Result>()
                list.add(itemResult)
                //用户选择的点位回调出去
                super.onScanResultCallback(
                    AnalyzeResult(result.imageData, result.imageFormat, result.frameMetadata, result.scanRect, list)
                )
            }
            multiplePoints.add(view)
        }
    }

    /**
     * 清除屏幕上的点位，后续如果想继续识别，请调用 [.startCamera]
     */
    fun cleanMultiplePoints() {
        for (multiplePoint in multiplePoints) {
            removeView(multiplePoint)
        }
        multiplePoints.clear()
    }

    /**
     * 清空点位并且继续识别
     */
    fun cleanMultiplePointsAndScan() {
        cleanMultiplePoints()
        //这里防止递归
        cameraScan.setAnalyzeImage(true)
        //        startCamera();
    }

    /**
     * 重写继续识别，把
     */
    override fun setAnalyzeImage(analyze: Boolean) {
        super.setAnalyzeImage(analyze)
        if (analyze && multiplePoints.size > 0) {
            cleanMultiplePointsAndScan()
        }
    }
}
